home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / Zoners Half-Life Tools / common / log.cpp < prev    next >
C/C++ Source or Header  |  2002-12-09  |  17KB  |  606 lines

  1. #ifdef HAVE_CONFIG_H
  2. #include "config.h"
  3. #endif
  4.  
  5. #ifdef ZHLT_NETVIS
  6. #ifdef SYSTEM_WIN32
  7. #define WIN32_LEAN_AND_MEAN
  8. #include <windows.h>
  9. #endif
  10. #endif
  11.  
  12. #ifdef STDC_HEADERS
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <stdarg.h>
  16. #endif
  17.  
  18. #ifdef HAVE_UNISTD_H
  19. #include <unistd.h>
  20. #endif
  21.  
  22. #ifdef ZHLT_NETVIS
  23. #include "../netvis/c2cpp.h"
  24. #endif
  25.  
  26. #include "cmdlib.h"
  27. #include "messages.h"
  28. #include "hlassert.h"
  29. #include "log.h"
  30. #include "filelib.h"
  31.  
  32. char*           g_Program = "Uninitialized variable ::g_Program";
  33. char            g_Mapname[_MAX_PATH] = "Uninitialized variable ::g_Mapname";
  34.  
  35. developer_level_t g_developer = DEFAULT_DEVELOPER;
  36. bool            g_verbose = DEFAULT_VERBOSE;
  37. bool            g_log = DEFAULT_LOG;
  38.  
  39. unsigned long   g_clientid = 0;
  40. unsigned long   g_nextclientid = 0;
  41.  
  42. static FILE*    CompileLog = NULL;
  43. static bool     fatal = false;
  44.  
  45. ////////
  46.  
  47. void            ResetTmpFiles()
  48. {
  49.     if (g_log)
  50.     {
  51.         char            filename[_MAX_PATH];
  52.  
  53.         safe_snprintf(filename, _MAX_PATH, "%s.bsp", g_Mapname);
  54.         unlink(filename);
  55.  
  56.         safe_snprintf(filename, _MAX_PATH, "%s.inc", g_Mapname);
  57.         unlink(filename);
  58.  
  59.         safe_snprintf(filename, _MAX_PATH, "%s.p0", g_Mapname);
  60.         unlink(filename);
  61.  
  62.         safe_snprintf(filename, _MAX_PATH, "%s.p1", g_Mapname);
  63.         unlink(filename);
  64.  
  65.         safe_snprintf(filename, _MAX_PATH, "%s.p2", g_Mapname);
  66.         unlink(filename);
  67.  
  68.         safe_snprintf(filename, _MAX_PATH, "%s.p3", g_Mapname);
  69.         unlink(filename);
  70.  
  71.         safe_snprintf(filename, _MAX_PATH, "%s.prt", g_Mapname);
  72.         unlink(filename);
  73.  
  74.         safe_snprintf(filename, _MAX_PATH, "%s.pts", g_Mapname);
  75.         unlink(filename);
  76.  
  77.         safe_snprintf(filename, _MAX_PATH, "%s.lin", g_Mapname);
  78.         unlink(filename);
  79.  
  80.         safe_snprintf(filename, _MAX_PATH, "%s.wic", g_Mapname);
  81.         unlink(filename);
  82.     }
  83. }
  84.  
  85. void            ResetLog()
  86. {
  87.     if (g_log)
  88.     {
  89.         char            logfilename[_MAX_PATH];
  90.  
  91.         safe_snprintf(logfilename, _MAX_PATH, "%s.log", g_Mapname);
  92.         unlink(logfilename);
  93.     }
  94. }
  95.  
  96. void            ResetErrorLog()
  97. {
  98.     if (g_log)
  99.     {
  100.         char            logfilename[_MAX_PATH];
  101.  
  102.         safe_snprintf(logfilename, _MAX_PATH, "%s.err", g_Mapname);
  103.         unlink(logfilename);
  104.     }
  105. }
  106.  
  107. void            CheckForErrorLog()
  108. {
  109.     if (g_log)
  110.     {
  111.         char            logfilename[_MAX_PATH];
  112.  
  113.         safe_snprintf(logfilename, _MAX_PATH, "%s.err", g_Mapname);
  114.         if (q_exists(logfilename))
  115.         {
  116.             Log(">> There was a problem compiling the map.\n"
  117.                 ">> Check the file %s.log for the cause.\n",
  118.                  g_Mapname);
  119.             exit(1);
  120.         }
  121.     }
  122. }
  123.  
  124. ///////
  125.  
  126. void            LogError(const char* const message)
  127. {
  128.     if (g_log && CompileLog)
  129.     {
  130.         char            logfilename[_MAX_PATH];
  131.         FILE*           ErrorLog = NULL;
  132.  
  133.         safe_snprintf(logfilename, _MAX_PATH, "%s.err", g_Mapname);
  134.         ErrorLog = fopen(logfilename, "a");
  135.  
  136.         if (ErrorLog)
  137.         {
  138.             fprintf(ErrorLog, "%s: %s\n", g_Program, message);
  139.             fflush(ErrorLog);
  140.             fclose(ErrorLog);
  141.             ErrorLog = NULL;
  142.         }
  143.         else
  144.         {
  145.             fprintf(stderr, "ERROR: Could not open error logfile %s", logfilename);
  146.             fflush(stderr);
  147.         }
  148.     }
  149. }
  150.  
  151. void CDECL      OpenLog(const int clientid)
  152. {
  153.     if (g_log)
  154.     {
  155.         char            logfilename[_MAX_PATH];
  156.  
  157. #ifdef ZHLT_NETVIS
  158.     #ifdef SYSTEM_WIN32
  159.         if (clientid)
  160.         {
  161.             char            computername[MAX_COMPUTERNAME_LENGTH + 1];
  162.             unsigned long   size = sizeof(computername);
  163.  
  164.             if (!GetComputerName(computername, &size))
  165.             {
  166.                 safe_strncpy(computername, "unknown", sizeof(computername));
  167.             }
  168.             safe_snprintf(logfilename, _MAX_PATH, "%s-%s-%d.log", g_Mapname, computername, clientid);
  169.         }
  170.         else
  171.     #endif
  172.     #ifdef SYSTEM_POSIX
  173.         if (clientid)
  174.         {
  175.             char            computername[_MAX_PATH];
  176.             unsigned long   size = sizeof(computername);
  177.  
  178.             if (gethostname(computername, size))
  179.             {
  180.                 safe_strncpy(computername, "unknown", sizeof(computername));
  181.             }
  182.             safe_snprintf(logfilename, _MAX_PATH, "%s-%s-%d.log", g_Mapname, computername, clientid);
  183.         }
  184.     #endif
  185. #endif
  186.         {
  187.             safe_snprintf(logfilename, _MAX_PATH, "%s.log", g_Mapname);
  188.         }
  189.         CompileLog = fopen(logfilename, "a");
  190.  
  191.         if (!CompileLog)
  192.         {
  193.             fprintf(stderr, "ERROR: Could not open logfile %s", logfilename);
  194.             fflush(stderr);
  195.         }
  196.     }
  197. }
  198.  
  199. void CDECL      CloseLog()
  200. {
  201.     if (g_log && CompileLog)
  202.     {
  203.         LogEnd();
  204.         fflush(CompileLog);
  205.         fclose(CompileLog);
  206.         CompileLog = NULL;
  207.     }
  208. }
  209.  
  210. //
  211. //  Every function up to this point should check g_log, the functions below should not
  212. //
  213.  
  214. #ifdef SYSTEM_WIN32
  215. // AJM: fprintf/flush wasnt printing newline chars correctly (prefixed with \r) under win32
  216. //      due to the fact that those streams are in byte mode, so this function prefixes 
  217. //      all \n with \r automatically.
  218. //      NOTE: system load may be more with this method, but there isnt that much logging going
  219. //      on compared to the time taken to compile the map, so its negligable.
  220. void            Safe_WriteLog(const char* const message)
  221. {
  222.     const char* c;
  223.     
  224.     if (!CompileLog)
  225.         return;
  226.  
  227.     c = &message[0];
  228.  
  229.     while (1)
  230.     {
  231.         if (!*c)
  232.             return; // end of string
  233.  
  234.         if (*c == '\n')
  235.             fputc('\r', CompileLog);
  236.  
  237.         fputc(*c, CompileLog);
  238.  
  239.         c++;
  240.     }
  241. }
  242. #endif
  243.  
  244. void            WriteLog(const char* const message)
  245. {
  246.  
  247. #ifndef SYSTEM_WIN32
  248.     if (CompileLog)
  249.     {
  250.         fprintf(CompileLog, message);
  251.         fflush(CompileLog);
  252.     }
  253. #else
  254.     Safe_WriteLog(message);
  255. #endif
  256.  
  257.     fprintf(stdout, message);
  258.     fflush(stdout);
  259. }
  260.  
  261. // =====================================================================================
  262. //  CheckFatal 
  263. // =====================================================================================
  264. void            CheckFatal()
  265. {
  266.     if (fatal)
  267.     {
  268.         hlassert(false);
  269.         exit(1);
  270.     }
  271. }
  272.  
  273. #define MAX_ERROR   2048
  274. #define MAX_WARNING 2048
  275. #define MAX_MESSAGE 2048
  276.  
  277. // =====================================================================================
  278. //  Error
  279. //      for formatted error messages, fatals out
  280. // =====================================================================================
  281. void CDECL      Error(const char* const error, ...)
  282. {
  283.     char            message[MAX_ERROR];
  284.     char            message2[MAX_ERROR];
  285.     va_list         argptr;
  286.     
  287.  #if defined( SYSTEM_WIN32 ) && !defined( __MINGW32__ ) && !defined( __BORLANDC__ )
  288.     {
  289.         char* wantint3 = getenv("WANTINT3");
  290.         if (wantint3)
  291.         {
  292.             if (atoi(wantint3))
  293.             {
  294.                 __asm
  295.                 {
  296.                     int 3;
  297.                 }
  298.             }
  299.         }
  300.     }
  301. #endif
  302.  
  303.     va_start(argptr, error);
  304.     vsnprintf(message, MAX_ERROR, error, argptr);
  305.     va_end(argptr);
  306.  
  307.     safe_snprintf(message2, MAX_MESSAGE, "Error: %s\n", message);
  308.     WriteLog(message2);
  309.     LogError(message2);
  310.  
  311.     fatal = 1;
  312.     CheckFatal();
  313. }
  314.  
  315. // =====================================================================================
  316. //  Fatal
  317. //      For formatted 'fatal' warning messages
  318. //      automatically appends an extra newline to the message
  319. //      This function sets a flag that the compile should abort before completing
  320. // =====================================================================================
  321. void CDECL      Fatal(assume_msgs msgid, const char* const warning, ...)
  322. {
  323.     char            message[MAX_WARNING];
  324.     char            message2[MAX_WARNING];
  325.  
  326.     va_list         argptr;
  327.  
  328.     va_start(argptr, warning);
  329.     vsnprintf(message, MAX_WARNING, warning, argptr);
  330.     va_end(argptr);
  331.  
  332.     safe_snprintf(message2, MAX_MESSAGE, "Error: %s\n", message);
  333.     WriteLog(message2);
  334.     LogError(message2);
  335.  
  336.     {
  337.         char            message[MAX_MESSAGE];
  338.         const MessageTable_t* msg = GetAssume(msgid);
  339.  
  340.         safe_snprintf(message, MAX_MESSAGE, "%s\nDescription: %s\nHowto Fix: %s\n", msg->title, msg->text, msg->howto);
  341.         PrintOnce(message);
  342.     }
  343.  
  344.     fatal = 1;
  345. }
  346.  
  347. // =====================================================================================
  348. //  PrintOnce
  349. //      This function is only callable one time. Further calls will be ignored
  350. // =====================================================================================
  351. void CDECL      PrintOnce(const char* const warning, ...)
  352. {
  353.     char            message[MAX_WARNING];
  354.     char            message2[MAX_WARNING];
  355.     va_list         argptr;
  356.     static int      count = 0;
  357.  
  358.     if (count > 0) // make sure it only gets called once
  359.     {
  360.         return;
  361.     }
  362.     count++;
  363.  
  364.     va_start(argptr, warning);
  365.     vsnprintf(message, MAX_WARNING, warning, argptr);
  366.     va_end(argptr);
  367.  
  368.     safe_snprintf(message2, MAX_MESSAGE, "Error: %s\n", message);
  369.     WriteLog(message2);
  370.     LogError(message2);
  371. }
  372.  
  373. // =====================================================================================
  374. //  Warning
  375. //      For formatted warning messages
  376. //      automatically appends an extra newline to the message
  377. // =====================================================================================
  378. void CDECL      Warning(const char* const warning, ...)
  379. {
  380.     char            message[MAX_WARNING];
  381.     char            message2[MAX_WARNING];
  382.  
  383.     va_list         argptr;
  384.  
  385.     va_start(argptr, warning);
  386.     vsnprintf(message, MAX_WARNING, warning, argptr);
  387.     va_end(argptr);
  388.  
  389.     safe_snprintf(message2, MAX_MESSAGE, "Warning: %s\n", message);
  390.     WriteLog(message2);
  391. }
  392.  
  393. // =====================================================================================
  394. //  Verbose
  395. //      Same as log but only prints when in verbose mode
  396. // =====================================================================================
  397. void CDECL      Verbose(const char* const warning, ...)
  398. {
  399.     if (g_verbose)
  400.     {
  401.         char            message[MAX_MESSAGE];
  402.  
  403.         va_list         argptr;
  404.  
  405.         va_start(argptr, warning);
  406.         vsnprintf(message, MAX_MESSAGE, warning, argptr);
  407.         va_end(argptr);
  408.  
  409.         WriteLog(message);
  410.     }
  411. }
  412.  
  413. // =====================================================================================
  414. //  Developer
  415. //      Same as log but only prints when in developer mode
  416. // =====================================================================================
  417. void CDECL      Developer(developer_level_t level, const char* const warning, ...)
  418. {
  419.     if (level <= g_developer)
  420.     {
  421.         char            message[MAX_MESSAGE];
  422.  
  423.         va_list         argptr;
  424.  
  425.         va_start(argptr, warning);
  426.         vsnprintf(message, MAX_MESSAGE, warning, argptr);
  427.         va_end(argptr);
  428.  
  429.         WriteLog(message);
  430.     }
  431. }
  432.  
  433. // =====================================================================================
  434. //  DisplayDeveloperLevel
  435. // =====================================================================================
  436. static void     DisplayDeveloperLevel()
  437. {
  438.     char            message[MAX_MESSAGE];
  439.  
  440.     safe_strncpy(message, "Developer messages enabled : [", MAX_MESSAGE);
  441.     if (g_developer >= DEVELOPER_LEVEL_MEGASPAM)
  442.     {
  443.         safe_strncat(message, "MegaSpam ", MAX_MESSAGE);
  444.     }
  445.     if (g_developer >= DEVELOPER_LEVEL_SPAM)
  446.     {
  447.         safe_strncat(message, "Spam ", MAX_MESSAGE);
  448.     }
  449.     if (g_developer >= DEVELOPER_LEVEL_FLUFF)
  450.     {
  451.         safe_strncat(message, "Fluff ", MAX_MESSAGE);
  452.     }
  453.     if (g_developer >= DEVELOPER_LEVEL_MESSAGE)
  454.     {
  455.         safe_strncat(message, "Message ", MAX_MESSAGE);
  456.     }
  457.     if (g_developer >= DEVELOPER_LEVEL_WARNING)
  458.     {
  459.         safe_strncat(message, "Warning ", MAX_MESSAGE);
  460.     }
  461.     if (g_developer >= DEVELOPER_LEVEL_ERROR)
  462.     {
  463.         safe_strncat(message, "Error", MAX_MESSAGE);
  464.     }
  465.     if (g_developer)
  466.     {
  467.         safe_strncat(message, "]\n", MAX_MESSAGE);
  468.         Log(message);
  469.     }
  470. }
  471.  
  472. // =====================================================================================
  473. //  Log
  474. //      For formatted log output messages
  475. // =====================================================================================
  476. void CDECL      Log(const char* const warning, ...)
  477. {
  478.     char            message[MAX_MESSAGE];
  479.  
  480.     va_list         argptr;
  481.  
  482.     va_start(argptr, warning);
  483.     vsnprintf(message, MAX_MESSAGE, warning, argptr);
  484.     va_end(argptr);
  485.  
  486.     WriteLog(message);
  487. }
  488.  
  489. // =====================================================================================
  490. //  LogArgs
  491. // =====================================================================================
  492. static void     LogArgs(int argc, char** argv)
  493. {
  494.     int             i;
  495.  
  496.     Log("Command line: ");
  497.     for (i = 0; i < argc; i++)
  498.     {
  499.         if (strchr(argv[i], ' '))
  500.         {
  501.             Log("\"%s\"", argv[i]);
  502.         }
  503.         else
  504.         {
  505.             Log("%s ", argv[i]);
  506.         }
  507.     }
  508.     Log("\n");
  509. }
  510.  
  511. // =====================================================================================
  512. //  Banner
  513. // =====================================================================================
  514. void            Banner()
  515. {
  516.     Log("%s " ZHLT_VERSIONSTRING " " HACK_VERSIONSTRING " (%s)\n", g_Program, __DATE__);
  517.     //Log("BUGGY %s (built: %s)\nUse at own risk.\n", g_Program, __DATE__);
  518.  
  519.     Log("Zoner's Half-Life Compilation Tools -- Custom Build\n"
  520.         "Based on code modifications by Sean 'Zoner' Cavanaugh\n"
  521.         "Based on Valve's version, modified with permission.\n"
  522.         MODIFICATIONS_STRING);
  523.  
  524. }
  525.  
  526. // =====================================================================================
  527. //  LogStart
  528. // =====================================================================================
  529. void            LogStart(int argc, char** argv)
  530. {
  531.     Banner();
  532.     Log("-----  BEGIN  %s -----\n", g_Program);
  533.     LogArgs(argc, argv);
  534.     DisplayDeveloperLevel();
  535. }
  536.  
  537. // =====================================================================================
  538. //  LogEnd
  539. // =====================================================================================
  540. void            LogEnd()
  541. {
  542.     Log("\n-----   END   %s -----\n\n\n\n", g_Program);
  543. }
  544.  
  545. // =====================================================================================
  546. //  hlassume
  547. //      my assume
  548. // =====================================================================================
  549. void            hlassume(bool exp, assume_msgs msgid)
  550. {
  551.     if (!exp)
  552.     {
  553.         char            message[MAX_MESSAGE];
  554.         const MessageTable_t* msg = GetAssume(msgid);
  555.  
  556.         safe_snprintf(message, MAX_MESSAGE, "%s\nDescription: %s\nHowto Fix: %s\n", msg->title, msg->text, msg->howto);
  557.         Error(message);
  558.     }
  559. }
  560.  
  561. // =====================================================================================
  562. //  seconds_to_hhmm
  563. // =====================================================================================
  564. static void seconds_to_hhmm(unsigned int elapsed_time, unsigned& days, unsigned& hours, unsigned& minutes, unsigned& seconds)
  565. {
  566.     seconds = elapsed_time % 60;
  567.     elapsed_time /= 60;
  568.  
  569.     minutes = elapsed_time % 60;
  570.     elapsed_time /= 60;
  571.  
  572.     hours = elapsed_time % 24;
  573.     elapsed_time /= 24;
  574.  
  575.     days = elapsed_time;
  576. }
  577.  
  578. // =====================================================================================
  579. //  LogTimeElapsed
  580. // =====================================================================================
  581. void LogTimeElapsed(float elapsed_time)
  582. {
  583.     unsigned days = 0;
  584.     unsigned hours = 0;
  585.     unsigned minutes = 0;
  586.     unsigned seconds = 0;
  587.  
  588.     seconds_to_hhmm(elapsed_time, days, hours, minutes, seconds);
  589.  
  590.     if (days)
  591.     {
  592.         Log("%.2f seconds elapsed [%ud %uh %um %us]\n", elapsed_time, days, hours, minutes, seconds);
  593.     }
  594.     else if (hours)
  595.     {
  596.         Log("%.2f seconds elapsed [%uh %um %us]\n", elapsed_time, hours, minutes, seconds);
  597.     }
  598.     else if (minutes)
  599.     {
  600.         Log("%.2f seconds elapsed [%um %us]\n", elapsed_time, minutes, seconds);
  601.     }
  602.     else
  603.     {
  604.         Log("%.2f seconds elapsed\n", elapsed_time);
  605.     }
  606. }